/**
 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
 */
package com.jeesite.modules.digitalize.service;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeesite.modules.digitalize.dao.DigitalizeReviewDao;
import com.jeesite.modules.digitalize.entity.DigitalizeReview;
import com.jeesite.modules.digitalize.entity.DigitalizeReviewDetail;
import com.jeesite.modules.digitalize.entity.dto.system.reviewproces.*;
import com.jeesite.modules.digitalize.entity.vo.system.reviewproces.ReviewprocesVo;
import com.jeesite.modules.digitalize.util.response.ResultVo;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * component_reviewprocesService
 * @author patronli
 * @version 2023-09-08
 */
@Service
public class DigitalizeReviewService extends ServiceImpl<DigitalizeReviewDao, DigitalizeReview> {

	@Autowired
    DigitalizeReviewDetailService detailService;
	@Autowired
	UserService userService;
	@Autowired
	private SystemService sysService;

    private void suppendUserName(List<ReviewprocesVo> list) {
        list.stream().forEach(chartVo -> {
            User employee = userService.get(chartVo.getCreateBy());
            if (employee != null) {
                chartVo.setCreateUserName(employee.getUserName());
            }
        });
    }
	/**
	 * @date 2023年09月13日 13:52:44
	 * @author patronli
	 * @Description: 流程列表
	 */
	public Page<ReviewprocesVo> pageList(@Validated ReviewprocesDto dto){
        Page page = this.lambdaQuery().eq(DigitalizeReview::getProjectId, dto.getProjectId()).page(new Page<DigitalizeReview>(dto.getPageNo(), dto.getPageSize()));
        List<ReviewprocesVo> reviewprocesVos = BeanUtil.copyToList(page.getRecords(), ReviewprocesVo.class);
        suppendUserName(reviewprocesVos);
        page.setRecords(reviewprocesVos);
		return page;
	}

	/**
	 * @date 2023年09月13日 13:53:00
	 * @author patronli
	 * @Description: 流程详情
	 */
	public ReviewprocesVo reviewprocesDetails(Long processId){
        DigitalizeReview data = this.getById(processId);
        if (data == null) {
            return null;
        }
        ReviewprocesVo reviewprocesVo = BeanUtil.copyProperties(data, ReviewprocesVo.class);
        reviewprocesVo.setReviewDetailList(detailService.lambdaQuery().eq(DigitalizeReviewDetail::getReviewId, processId).list());
		return reviewprocesVo;
	}

	/**
	 * @date 2023年09月13日 13:53:15
	 * @author patronli
	 * @Description: 新增流程
	 */
	@Transactional
	public ResultVo reviewprocesAdd(@Validated ReviewprocesAddDto dto){
		//先新增主流程表
		DigitalizeReview reviewproces = new DigitalizeReview().setReviewName(dto.getReviewName()).setRemarks(dto.getRemarks()).setProjectId(dto.getProjectId());
		this.save(reviewproces);

		//新增流程详情表
		List<ReviewprocesDetailAddDto> details = dto.getDetails();
		details = details.stream().sorted(Comparator.comparing(ReviewprocesDetailAddDto::getSequence)).collect(Collectors.toList());
        List<DigitalizeReviewDetail> detailList = BeanUtil.copyToList(details, DigitalizeReviewDetail.class);
        ResultVo resultVo = checkSequence(detailList);
        if (resultVo.isFail()) {
            return resultVo;
        }
        detailList.stream().forEach(item -> item.setReviewId(reviewproces.getId()).setDelStatus(0));
        detailService.saveBatch(detailList);
		return ResultVo.success(reviewproces);
	}

    private ResultVo checkSequence(List<DigitalizeReviewDetail> detailList) {
        int sequence = 1;
        for (DigitalizeReviewDetail digitalizeReviewDetail : detailList) {
            if (digitalizeReviewDetail.getSequence() != sequence) {
                return ResultVo.failure("审核流程顺序必须从1开始，且不能有间隔");
            }
            sequence++;
        }
        return ResultVo.success();
    }

    /**
	 * @date 2023年09月13日 16:59:49
	 * @author patronli
	 * @Description: 更新审核流程
	 */
	@Transactional
	public ResultVo reviewprocesUpdate(@Validated ReviewprocesUpdateDto dto){
		//先更新主表
        this.lambdaUpdate().set(DigitalizeReview::getRemarks, dto.getRemarks()).set(DigitalizeReview::getReviewName, dto.getReviewName()).eq(DigitalizeReview::getId, dto.getId()).update();
		//详情表 先删后增
        detailService.lambdaUpdate().eq(DigitalizeReviewDetail::getReviewId, dto.getId()).remove();
		//新增流程详情表
        List<ReviewprocesDetailAddDto> details = dto.getDetails();
        details = details.stream().sorted(Comparator.comparing(ReviewprocesDetailAddDto::getSequence)).collect(Collectors.toList());
        List<DigitalizeReviewDetail> detailList = BeanUtil.copyToList(details, DigitalizeReviewDetail.class);
        ResultVo resultVo = checkSequence(detailList);
        if (resultVo.isFail()) {
            return resultVo;
        }
        detailList.stream().forEach(item -> item.setReviewId(dto.getId()).setDelStatus(0));
        detailService.saveBatch(detailList);

		//String content = LogConstants.REVIEWPROCES_UPDATE;
		//if (Constants.SOURCE_PROJECT_1.equals(dto.getSource())) {//企业
		//	content = LogConstants.REVIEWPROCES_REGION_UPDATE.replace(Constants.REPLACE_KEY_0, sysService.getOfficeName(dto.getOfficeId()));
		//}
		//ComponentLog log = new ComponentLog();
		//log.setContent(content);
		//logService.save(log);
		return ResultVo.success();
	}

	/**
	 * @date 2023年09月13日 17:00:04
	 * @author patronli
	 * @Description: 删除审核流程
	 */
	public ResultVo reviewprocesDel(@Validated DeleteIdListDTO dto){
        this.removeByIds(dto.getIdList());
        detailService.lambdaUpdate().in(DigitalizeReviewDetail::getReviewId, dto.getIdList()).remove();
		//String content = LogConstants.REVIEWPROCES_DEL;
		//if (Constants.SOURCE_PROJECT_1.equals(dto.getSource())) {//企业
		//	content = LogConstants.REVIEWPROCES_REGION_DEL.replace(Constants.REPLACE_KEY_0, sysService.getOfficeName(dto.getOfficeId()));
		//}
		//ComponentLog log = new ComponentLog();
		//log.setContent(content);
		//logService.save(log);
		return ResultVo.success();
	}
}